react系列(12)React+Webpack的组合搭建 您所在的位置:网站首页 gimp 官网 下载 镜像源 react系列(12)React+Webpack的组合搭建

react系列(12)React+Webpack的组合搭建

2022-06-02 17:35| 来源: 网络整理| 查看: 265

React是纯View层,但在最新的React V16版本中,按传统的纯js脚本开发已经不能适应项目的需要,配合Webpack打包,可以够更便捷地管理项目和更新插件;再者,使用ES6开发,将大大地提高团队地开发效率。本篇主要是介绍如何部署React+Webpack组合搭建,那么我们一步步来吧。

一.创建目录结构

创建一个web项目ReactWebpack,目录结构如图所示:

app目录:存放核心代码。

components目录:存放React组件。

css目录:存放样式文件。

build目录:存放打包编译后的js文件。

index.html:展示页。

main.js:入口js文件。

  二.安装cnpm镜像

假设你本机已经安装nodejs,可以使用命令行npm,我用的版本是node-v6.0.0-x64.msi,百度即可下载。

为什么用cnpm?因为cnpm是淘宝npm镜像,下载速度会更流畅,当然也可以使用npm。

安装命令行:

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

 

三.创建package.json文件

package.json是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等,通过这个文件即可知道您的项目跑起来需要哪些模块库,项目作者、版本等。

在dos环境下,检索至项目根目录,执行命令行:

$ npm init

输入项目名称:react_demo,其它直接enter即可,成功后如图所示:

此时,会在项目的根目录下多了一个package.json文件,文件内容如下:

  四.安装webpack

webpack主要用于对项目的打包和管理,安装成功后,会在项目根目录上多了一个node_modules文件夹,里面是存放所有npm下载的库模块。安装命令行:

$ cnpm install --save-dev webpack

安装成功后如图所示:

  五.创建webpack.config.js文件

webpack.config.js是打包配置文件,文件内容如下:

var webpack = require('webpack'); module.exports = { //根目录 context: __dirname + "", //文件入口 entry: { index: './app/main.js' }, //文件出口 output: { path: __dirname + "/build", // 设置输出目录 filename: '[name].bundle.js', // 输出文件名 }, module: { //loaders加载器 loaders: [{ test: /\.(js|jsx)$/, //【一个匹配loaders所处理的文件的拓展名的正则表达式,这里用来匹配js和jsx文件(必须)】 exclude: /node_modules/, //【屏蔽不需要处理的文件(文件夹)(可选)】 loader: 'babel-loader' //【loader的名称(必须)】此处为可以转换ES6和JSX语法的加载器 }, { test: /\.css$/, loader: "style!css" //.css文件使用 style-loader 和 css-loader 来处理 }, { test: /\.(jpeg|png|gif|svg)$/i, loader: 'url-loader?limit=8192&name=[name].[ext]' //图片文件使用 url-loader来处理,小于8kb的直接转为base64 } ] }, // 插件 plugins: [ // 默认会把所有入口节点的公共代码提取出来,生成一个common.js //new webpack.optimize.CommonsChunkPlugin('common'), // 压缩代码抬头注释 new webpack.BannerPlugin('此处添加打包抬头注释!'), // 代码压缩 new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) ], //由于压缩后的代码不易于定位错误,配置该项后发生错误时即可采用source-map的形式直接显示你出错代码的位置 devtool: 'eval-source-map', //其它解决方案配置 resolve: { // 配置简写,配置过后,书写该文件路径的时候可以省略文件后缀。如require("common") extensions: ['.js', '.jsx', '.coffee'] } }

详细的格式我就不解释了,里面都有注释。

 

六.安装React

执行命令行:

$ cnpm install --save-dev react react-dom

 

七.安装babel

执行命令行:

cnpm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react

在项目根目录下新建.babelrc文件,就是只有后缀名的文件,如图所示:

 

文件内容如下:

//.babelrc { "presets": [ "react", "es2015" ] }

Babel其实可以完全在webpack.config.js中进行配置。但是考虑到babel具有非常多的配置选项,在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂,因此一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中。

 

八.添加代码

新建如下图目录所示文件(其中index.bundle.js为打包时才会有的文件,可以不用新建):

Component.jsx脚本如下:

import React from 'react'; class Component extends React.Component { constructor(props) { super(props); this.state = {}; } handleClick(e) { } render() { return ( Hello {this.props.name}! ) } } //导出组件 export default Component;

color.css脚本如下:

.red{ color: red; }

main.js脚本如下:

//ES6 import React from 'react'; import ReactDom from 'react-dom'; import Component from './components/Component.jsx'; ReactDom.render( , document.getElementById('content') );

(注)SayHello.jsx为ES5写法,后面会介绍到。

 

九.打包

执行命令行:

$ webpack -d

(注)监察打包 webpack --watch 其中copy+c结束监察,监察是指只要代码有变动即会自动打包。 打包成功后会在build目录下自动生成一个index.bundle.js文件,打开index.html文件,写入脚本:

打开浏览器运行,运行结果:

 

 

 

至此,我们已经成功部署好了React+Webpack组合开发环境。当然,毕竟并不是所有初学者都学过ES6语法,那么我们可否用ES5组合开发呢?答案是可以的。我们把SayHello.jsx写入脚本如下:

var React = require('react'); var createReactClass = require('create-react-class'); var SayHello = createReactClass({ render:function(){ var style = {color:"red"}; return (Hello ES5(2)); } }); exports = module.exports = SayHello;

然后更改main.js脚本为:

//ES6 //import React from 'react'; //import ReactDom from 'react-dom'; //import Component from './components/Component.jsx'; // //ReactDom.render( // , // document.getElementById('content') //); //ES5 写法1 var React = require('react'); var ReactDOM = require('react-dom'); var createReactClass = require('create-react-class'); var SayHello = createReactClass({ render:function(){ return (Hello ES5(1)); } }); ReactDOM.render(,document.getElementById("content")); //ES5 写法2 //var React = require('react'); //var ReactDOM = require('react-dom'); //var createReactClass = require('create-react-class'); //var SayHello = require('./components/SayHello'); //ReactDOM.render(,document.getElementById("content"));

打包后执行结果(上例中写法2为引入外部组件方式,效果与写法1一致):

 

 

(新补充)关于webpack -d命令打包失败问题

有反馈说根据上面代码敲了一遍,发现打包不了。这是因为我再写这个demo的时候用的是webpack3.x版本,现在最新版本已经是4.23.0,可以通过命令webpack -v查看自己的版本。此处打包建议需要版本一致,所以可修改package.json文件,修改如下:

{ "name": "react_demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack" }, "author": "huangzp", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "create-react-class": "^15.6.2", "react": "^16.1.1", "react-dom": "^16.1.1", "webpack": "^4.23.0" } }

然后通过命令先把原有node_modules清理:

npm install rimraf -g rimraf node_modules

再重新初始化:

npm install

关于使用webpack4.x还有一个地方需要修改,就是该版本不再支持UglifyJs代码压缩方法,所以webpack.config.js文件修改如下:

var webpack = require('webpack'); module.exports = { //根目录 context: __dirname + "", //文件入口 entry: { index: './app/main.js' }, //文件出口 output: { path: __dirname + "/build", // 设置输出目录 filename: '[name].bundle.js', // 输出文件名 // filename:'./build/[name].bundle.js' }, module: { //rules加载器 rules: [{ test: /\.(js|jsx)$/, //【一个匹配rules所处理的文件的拓展名的正则表达式,这里用来匹配js和jsx文件(必须)】 exclude: /node_modules/, //【屏蔽不需要处理的文件(文件夹)(可选)】 loader: 'babel-loader' //【loader的名称(必须)】此处为可以转换ES6和JSX语法的加载器 }, { test: /\.css$/, loader: "style-loader!css-loader" //.css文件使用 style-loader 和 css-loader 来处理 }, { test: /\.(jpeg|png|gif|svg)$/i, loader: 'url-loader?limit=8192&name=[name].[ext]' //图片文件使用 url-loader来处理,小于8kb的直接转为base64 } ] }, // 插件 plugins: [ // 默认会把所有入口节点的公共代码提取出来,生成一个common.js //new webpack.optimize.CommonsChunkPlugin('common'), // 压缩代码抬头注释 new webpack.BannerPlugin('此处添加打包抬头注释!'), // 代码压缩 // new webpack.optimize.UglifyJsPlugin({ // compress: { // warnings: false // } // }) ], // 代码压缩 optimization: { minimize: false // 当发布环境打包时需设为true }, //由于压缩后的代码不易于定位错误,配置该项后发生错误时即可采用source-map的形式直接显示你出错代码的位置 devtool: 'eval-source-map', //其它解决方案配置 resolve: { // 配置简写,配置过后,书写该文件路径的时候可以省略文件后缀。如require("common") extensions: ['.js', '.jsx', '.coffee'] } }

这样,webpack -d即可打包成功。

 

(新补充)综合应用参考案例 // 综合应用ES5 var React = require('react'); var ReactDOM = require('react-dom'); var createReactClass = require('create-react-class'); var $ = require('jquery'); // 内联样式 var stateCSS = { cursor: "pointer" }; // 混合函数对象 var mixinCommon = { componentWillMount: function() { console.log("mix componentWillMount!"); } } // 子组件数据传递 var ChildComp = createReactClass({ componentDidMount: function() { this.setState({ dataCallBackFun: this.props.callBackFun }); }, getInitialState: function() { return { dataFromParant: "", dataCallBackFun: null, respData: "" } }, // 静态方法 statics: { doMethod: function() { console.log("静态方法被调用!"); } }, setInputData: function(value) { this.setState({ dataFromParant: value }); }, childDataChangeHandle: function(e) { this.setState({ respData: e.target.value }); }, clickHandle: function(e) { this.state.dataCallBackFun(this.state.respData); }, staticHandle: function(e) { ChildComp.doMethod(); }, render: function() { return( 子组件回调 静态函数调用 ); } }); // 列表组件展示 var ListComp = createReactClass({ render: function() { return( { this.props.listData.map(function(item,index){ return ID:{item.id},值:{item.data} }) } ); } }); // 父组件 var MyComp = createReactClass({ // 混合函数mixin mixins: [mixinCommon], // 默认参数 getDefaultProps: function() { return { msg: "helloui.prop" } }, // 状态变量 getInitialState: function() { return { param: "helloui.state", inValue: "", callBackValue: "", list: [] } }, // 操作事件 clickHandle: function(e) { this.setState({ param: "hello.clicked" }); }, // 父子组件参数传递 inputDataChangeHandle: function(e) { this.setState({ inValue: e.target.value }); }, // 父子组件参数传递 putDataToChildHandle: function(e) { this.refs.childcomp.setInputData(this.state.inValue); }, // 父子组件参数传递 childCallBackFunHandle: function(resp) { this.setState({ callBackValue: resp }); }, // 生命钩子函数 componentDidMount: function() { console.log('Mount挂载完成'); this.setState({ list: [{ id: "id1", data: "data1" }, { id: "id2", data: "data2" }, { id: "id3", data: "data3" } ] }); // ajax请求 $.ajax({ url: "https://api.github.com/users/octocat/gists", data: "", type: 'GET', timeout: 30000, error: function(response, state) { console.log(response); }, success: function(response, state) { console.log(response) } }); }, // 渲染 render: function() { return( 默认参数:{this.props.msg} 状态变量:{this.state.param} 父组件入参 ); } }); ReactDOM.render(, document.getElementById("content")); // Element + Factory 用法 var EleComp = createReactClass({ render: function() { return( {this.props.text} ); } }); var EleFactory = React.createFactory(EleComp); var MyElements = React.createElement('div', null, EleFactory({ text: 'element1' }), EleFactory({ text: 'element2' })); ReactDOM.render(MyElements, document.getElementById("elements"));

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有